<script setup lang="ts">
import {
  ref,
  reactive,
  toRefs,
  watch,
  watchEffect,
  onBeforeMount,
  onMounted,
} from "vue";

// watch 默认情况下，是被动触发的，仅在侦听源发生变化时被调用；访问被侦听状态的先前值和当前值

// 侦听一个 getter
const state = reactive({
  user: {
    username: "xiaoming",
    orgcode: "ZJ",
  },
  count: 0,
});
watch(
  () => state.count,
  (count, prevCount) => {
    console.log("watch state.count", count, prevCount);
  }
);

// 直接侦听一个 ref
const count = ref(0);
watch(count, (count, prevCount) => {
  console.log("watch count", count, prevCount);
});
// 强制立即执行侦听，组件启动就获取一次值
watch(
  count,
  (count, prevCount) => {
    console.log("watch count 强制立即执行侦听", count, prevCount);
  },
  { deep: true, immediate: true }
);

const refObj = ref({
  user: {
    username: "xiaoming",
    orgcode: "ZJ",
  },
  count: 0,
});

// 侦听多个源
watch([state.user, count], ([user, count], [prevUser, prevCount]) => {
  console.log("watch mutil user", user, prevUser);
  console.log("watch mutil count", count, prevCount);
});

// 立即侦听
watchEffect(() => {
  console.log("watchEffect count", count.value);
  console.log("watchEffect state.count", state.count);
  console.log("watchEffect state.user", state.user);
});

onMounted(() => {
  console.log("onMounted");
  console.log("onMounted refObj.value", refObj.value);
  console.log("onMounted state", state);
  console.log("onMounted toRefs(state)", toRefs(state));
  console.log("onMounted {...toRefs(state)}", { ...toRefs(state) });
  //浅拷贝，count 去掉了 proxy，user 没有
  console.log("onMounted Object.assign({}, state)", Object.assign({}, state));
  //深拷贝
  console.log(
    "onMounted JSON.parse(JSON.stringify(state)",
    JSON.parse(JSON.stringify(state))
  );
});
onBeforeMount(() => console.log("onBeforeMount"));

const onClick = () => {
  count.value = count.value + 1;
  state.count++;
  state.user.username = "admin_" + new Date().getTime();

  const obj1 = { a: 0, b: { c: 0 } };
  const obj2 = {
    c: 4,
    d: 5,
  };
  // 浅拷贝，Object.assign() 拷贝的是属性值。假如源对象的属性值是一个对象的引用，那么它也只指向那个引用
  const obj3 = Object.assign(obj2, obj1);
  const obj4 = Object.assign({}, obj1);
  // 深拷贝 Deep Clone
  let obj5 = JSON.parse(JSON.stringify(obj1));
};
</script>
<template>
  <h1>
    ref、reactive、watch、watchEffect、onMounted、onBeforeMount、浅拷贝、深拷贝
  </h1>
  <p>
    响应式数据声明 ref、reactive，ref 推荐定义基本数据类型，reactive
    定义复杂数据类型
    <br />
    watch 结果可以在控制台查看
    <br />
    count：{{ count }} 、 state.count：{{ state.count }}、state.user：{{
      state.user
    }}
  </p>
  <a href="javascript:void(0)" @click="onClick">点击</a>
</template>
